import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn import preprocessing

from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import RidgeCV
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet

from sklearn.metrics import r2_score
import pandas as pd

def load_data():#导入数据
    global x_data,y_data,name_data
       
    data = pd.read_csv("boston_housing.csv")
    y_data = data['MEDV']
    x_data = data.drop('MEDV', axis = 1)

    y_data=np.array(y_data)
    x_data=np.array(x_data)
    name_data =list(data.columns)#返回对象列索引


def show_data():#描绘数据散点图
    global x_data,y_data,name_data
    for i in range(13):
        plt.subplot(2,7,i+1)
        x=x_data[:,i]
        y=y_data[:]
        plt.scatter(x,y)
        plt.title(name_data[i])
    plt.show()

def wash_data():#清洗数据，去除房价低于50的数据，提取"RM"、'PTRATIO'、'LSTAT'
    global x_data,y_data,name_data
    
    i_=[]
    for i in range(len(y_data)):
        if y_data[i] == 50:
            i_.append(i)#存储房价等于50 的异常值下标

    x_data = np.delete(x_data,i_,axis=0)#删除房价异常值数据
    y_data = np.delete(y_data,i_,axis=0)#删除异常值
    #name_data = dataset.feature_names

    j_=[]
    for i in range(13):
        if name_data[i] == 'RM'or name_data[i] == 'PTRATIO'or name_data[i] == 'LSTAT':
            continue
        j_.append(i)#存储其他次要特征下标

    x_data = np.delete(x_data,j_,axis=1)#在总特征中删除次要特征



def traintestsplit():#数据分割，一部分用于验证、一部分用于训练
    global x_data,y_data,name_data

    X_train,X_test,y_train,y_test=train_test_split(x_data,y_data,random_state=0,test_size=0.20)

    return X_train,X_test,y_train,y_test


def Normalizedprocessing(X_train,X_test,y_train,y_test):#数据标归一化处理
    #分别初始化对特征和目标值的标准化器
    min_max_scaler = preprocessing.MinMaxScaler()
    #分别对训练和测试数据的特征以及目标值进行标准化处理
    X_train=min_max_scaler.fit_transform(X_train)
    X_test=min_max_scaler.fit_transform(X_test)
    y_train=min_max_scaler.fit_transform(y_train.reshape(-1,1))#reshape(-1,1)指将它转化为1列，行自动确定
    y_test=min_max_scaler.fit_transform(y_test.reshape(-1,1))#reshape(-1,1)指将它转化为1列，行自动确定

    return X_train,X_test,y_train,y_test


load_data() #数据提取

wash_data()

##show_data()

X_train,X_test,y_train,y_test=traintestsplit()  #数据分割

Normalizedprocessing(X_train,X_test,y_train,y_test) #数据归一化

#使用线性回归模型LinearRegression对波士顿房价数据进行训练及预测

lr=LinearRegression()

#lr=Ridge()

#lr=RidgeCV()

#lr=Lasso()

#lr=ElasticNet()

#使用训练数据进行参数估计
lr.fit(X_train,y_train) #训练模型

#回归预测R2测试
lr_y_predict=lr.predict(X_test)
score = r2_score(y_test, lr_y_predict)
print(score)


s=list(range(len(y_test)))
#print(X_test)
name=["RM","LSTAT","PTRATIO"]
for i in range(3):
    plt.subplot(1,3,i+1)
    plt.scatter(X_test[:,i],y_test,c="r")
    plt.scatter(X_test[:,i],lr_y_predict,c="y")
    plt.title(name[i])
plt.show()


client_data = [[5, 17, 15], # 客户 1
               [4, 32, 22], # 客户 2
               [8, 3, 12]]  # 客户 3

# 进行预测
predicted_price = lr.predict(client_data)
for i, price in enumerate(predicted_price):
    print("Predicted selling price for Client {}'s home: ${:,.2f}".format(i+1, price))














